home *** CD-ROM | disk | FTP | other *** search
- /*
- ### solve implicit nonlinear equation by secant's method ###
-
- Input: (double *) pxv (dim=var_dim): current coords
- (double *) pvx1, *pvx2 (dim=var_dim/2): two guesses
- (only coords parts of the phase space variables are used here).
- (int) dim: the dimension of the phase space
- Output: (double *) pvx1 (dim=var_dim): returns the coordinates of the next
- orbit.
- */
- symp_sqze(pvx1,pvx2,pvx,time,time_step,dim)
- double *pvx1,*pvx2,*pvx,time,time_step;
- int dim;
- {
- int i,j,it,max_secant,index,iswit,ii,i2,dim2,identity;
- double eps,epsf,err;
- double **vnew,**vjac,*dvec,*dvecn,**fiter,*vfull,*vfull2,*dvector(),**dmatrix();
- double fabs(),log10();
- extern int stop;
- extern double cutoff,*param;
- extern int (*f_p)();
-
-
- dim2 = dim/2;
- vnew = dmatrix(0,dim2-1,0,1);
- vjac = dmatrix(0,dim2-1,0,dim2-1);
- fiter = dmatrix(0,dim2-1,0,dim2);
- dvec = dvector(0,dim2-1);
- dvecn = dvector(0,dim2-1);
- vfull = dvector(0,dim-1);
- vfull2 = dvector(0,dim-1);
- eps = 1.e-14;
- epsf = 1.e-16;
- max_secant = 21;
- for(i=0;i<dim2;i++){
- i2 = i*2;
- vnew[i][0]= *(pvx1+i2);
- vnew[i][1]= *(pvx2+i2);
- }
- /*
- it=0;
- printf("%%v%d x1,x2=%18.10e %18.10e z1,z2=%18.10e %18.10e\n",it,vnew[0][0],vnew[0][1],vnew[1][0],vnew[1][1]);
- */
- for(it = 0;it <max_secant;it++){
- for(i=0;i<dim2;i++){
- if(vnew[i][1] > cutoff || vnew[i][1] < - cutoff) {
- system_mess_proc(1,"Orbits appear to diverge off to an infinity! Stop!");
- stop=1;
- goto done;
- }
- }
- for(index=0;index<dim2+1;index++){
- for(i=0;i<dim2;i++){
- i2=i*2;
- vfull[i2]=vnew[i][0];
- vfull[i2+1] = *(pvx+i2+1);
- }
- if(index != dim2)
- vfull[2*index] = vnew[index][1];
- /*
- printf("%%vfull[%d] %18.12f %18.12f %18.12f %18.12f\n",index,vfull[0],vfull[1],vfull[2],vfull[3]);
- */
- (int) f_p(vfull2,1,vfull,param,time,dim);
- /*
- printf("%%vfull2[%d] %18.12f %18.12f %18.12f %18.12f\n",index,vfull2[0],vfull2[1],vfull2[2],vfull2[3]);
- */
- for(i=0;i<dim2;i++){
- i2=i*2;
- fiter[i][index]= vfull[i2] - *(pvx+i2) - time_step * vfull2[i2];
- }
- /*
- printf("%%fiter[][%d] %18.12f %18.12f\n",index,fiter[0][index],fiter[1][index]);
- */
- }
- for(i=0;i<dim2;i++){
- for(j=0;j<dim2;j++)
- vjac[i][j]=(fiter[i][j]-fiter[i][dim2])/(vnew[j][1]-vnew[j][0]);
- dvec[i]= -fiter[i][dim2];
- }
- printf("%%vjac %18.12f %18.12f %18.12f %18.12f\n",vjac[0][0],vjac[0][1],vjac[1][0],vjac[1][1]);
- /*
- printf("%%dvec %18.12f %18.12f\n",dvec[0],dvec[1]);
- */
-
- /* see if the jacobian is identity */
- identity = 1;
- for(i=0;i<dim2;i++){
- for(j=0;j<dim2;j++){
- if(i=j){
- if(vjac[i][j]!=1.){
- identity=0;
- break;
- }
- }
- else if (vjac[i][j]!=0.){
- identity = 0;
- break;
- }
- }
- if(identity==0)
- break;
- }
-
- if(identity){
- system_mess_proc(1,"symp_sqze: Jacobian=Identity. Use explicit symp integration!");
- stop = 1;
- return;
- }
-
- stop = (int) linsol(dvecn,vjac,dvec,dim2);
-
- if(stop) {
- system_mess_proc(1,"symp_sqze: sigular matrix");
- goto done;
- }
- /*
- printf("dvecn %18.10e %18.10e dvec %18.10e %18.10e\n",dvecn[0],dvecn[1],dvec[0],dvec[1]);
- */
-
- /* testing for adequacy of roots */
- iswit =1;
- for(i=0;i<dim2;i++){
- if(fabs(dvecn[i]) >eps)
- iswit = 0;
- vnew[i][1]=vnew[i][0];
- vnew[i][0]=vnew[i][0]+dvecn[i];
- }
- if(iswit)
- goto done;
- iswit =1;
- for(i=0;i<dim2;i++){
- if( fabs(dvec[i]) > epsf)
- iswit = 0;
- }
- if(iswit)
- goto done;
- /*
- printf("%%v%d %18.10e %18.10e %18.10e %18.10e\n",it,vnew[0][0],vnew[0][1],vnew[1][0],vnew[1][1]);
- */
- printf("\n");
- }
-
- done:
- for(i=0;i<dim2;i++){
- i2 = i*2;
- *(pvx1+i2) = vnew[i][0];
- *(pvx2+i2) = vnew[i][1];
- }
- err = 1.e-16;
- for(i=0;i<dim2;i++){
- if(err > dvec[i])
- err = dvec[i];
- }
- (void) free_dmatrix(vnew,0,dim2-1,0,1);
- (void) free_dmatrix(vjac,0,dim2-1,0,dim2-1);
- (void) free_dmatrix(fiter,0,dim2-1,0,dim2);
- (void) free_dvector(dvec,0,dim2-1);
- (void) free_dvector(dvecn,0,dim2-1);
- (void) free_dvector(vfull,0,dim-1);
- (void) free_dvector(vfull2,0,dim-1);
- }
-